//Scott Rogowski and Yipeng Huang
//smr2167 yh2315

`define CHIP_CYCLE #10 // set one clk cycle to 10 time units
`define CHIP_HALF_CYCLE #5 // half a clock cycle
`define CHIP_RISE_CLK @(posedge clk)
`define CHIP_DEL #1

module bench;
	`include "./params.def"
	//Standard
		reg clk = 1;
		reg reset = 1;

	//Instruction stage
		//From the mipsPipe
		wire inst_o_valid;
		wire [WIDTH-1:0] inst_o_addr;

		//To the mipsPipe
		reg inst_i_valid;
		reg [WIDTH-1:0] inst_i;


	//Data stage
		//From the mipsPipe
		wire data_o_rw;
		wire data_o_valid;
		wire [WIDTH-1:0] data_o_addr;
		wire [WIDTH-1:0] data_o_value;

		//To the mipsPipe
		reg data_i_valid;
		reg [WIDTH-1:0] data_i;

	mipspipe dut (
		//Standard
			.clk(clk),
			.reset(reset),

		//Instruction stage
			//From the mipsPipe
			.inst_o_valid(inst_o_valid),
			.inst_o_addr(inst_o_addr[WIDTH-1:0]),

			//To the mipsPipe
			.inst_i_valid(inst_i_valid),
			.inst_i(inst_i[WIDTH-1:0]),


		//Data stage
			//From the mipsPipe
			.data_o_rw(data_o_rw),
			.data_o_valid(data_o_valid),
			.data_o_addr(data_o_addr[WIDTH-1:0]),
			.data_o_value(data_o_value[WIDTH-1:0]),

			//To the mipsPipe
			.data_i_valid(data_i_valid),
			.data_i(data_i[WIDTH-1:0])
		);

	// set up the clock
	always `CHIP_HALF_CYCLE clk = ~clk;

	initial	begin
		$dumpvars;
		$vcdpluson;
		$pli_init;
		end

	always @(posedge clk) begin
			
		/* capture outputs to pass on to C model */
		$pli_capture(
			inst_o_valid,
			inst_o_addr,

			data_o_rw,
			data_o_valid,
			data_o_addr,
			data_o_value
			);
			
		`CHIP_DEL;
		
		/* compare outputs to expected outputs, terminate on error */
		$pli_update;
	
		/* drive new inputs for the dut */
		//TODO We are driving first to set to ensure that one clock cycle passes between data and return.  This may not be the correct way to do this...
		//TODO, WHY ARE WE NOT PASSING THE CLOCK????
		$pli_drive(
			reset,

			inst_i_valid,
			inst_i,

			data_i_valid,
			data_i
			
			);
		end
	endmodule
